package com.fdb.efp.nls.service.impl.dw;

import com.fdb.basic.framework.core.constant.CurrencyConstant;
import com.fdb.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.fdb.basic.framework.core.constant.SDicCertTypeEnum;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.SpringContextUtils;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.basic.sequence.service.DefaultPatternDescriptor;
import com.fdb.basic.sequence.service.PatternDescriptor;
import com.fdb.basic.sequence.service.facade.PatternedLimitableSeqService;
import com.fdb.efp.nls.common.constant.BdLoanConstant;
import com.fdb.efp.nls.service.domain.TxtFileLoadBean;
import com.fdb.efp.nls.service.domain.dw.BdSxapplyBean;
import com.fdb.efp.nls.service.facade.dw.BdLmtPrdContBatchService;
import com.fdb.efp.nls.service.util.DueDataUtil;
import com.fdb.efp.nls.service.util.SDicMappingUtil;
import com.fdb.efp.nls.service.util.TxtFileLoadPluginBatch;
import com.fdb.efp.limit.service.facade.LmtPrdContService;
import com.fdb.efp.limit.service.vo.LmtPrdContVO;
import com.fdb.efp.nls.service.facade.AccoutErroTempService;
import com.fdb.efp.nls.service.vo.AccoutErroTempVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.fdb.basic.sequence.service.DefaultPatternDescriptor.*;

/**
 * 
 * 二阶段百度数据移植-数据移植-授信申请信息同步 <br>
 * 根据ODS卸载的实时进件-授信申请信息生成额度信息<br>
 * 
 * @author ludayong
 * @since 2019年5月7日 上午9:51:52
 * @version 1.0
 */
@Service("bdLmtPrdContBatchService")
public class BdLmtPrdContBatchServiceImpl implements BdLmtPrdContBatchService {

	private static Logger logger = LoggerFactory.getLogger(BdLmtPrdContBatchServiceImpl.class);
	private static final PatternDescriptor pattern = DefaultPatternDescriptor.of("lmt" + YEAR_4 + MONTH + DAY + SEQ, 8);

	@Autowired
	@Qualifier("lmtPrdContService")
	private LmtPrdContService lmtPrdContService;// 额度信息

	@Autowired
	@Qualifier("accoutErroTempService")
	private AccoutErroTempService accoutErroTempService;// 同步文件记录异常信息

	/**
	 * 
	 * 根据存量的实时进件-授信申请信息生成额度信息 <br>
	 * 0.1:ludayong:2019年5月7日 上午10:00:36:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 上午10:00:36
	 * @date 2019年5月7日 上午10:00:36
	 * @version 0.1
	 */
	@Override
	public boolean batchSyncLmtPrdCont(String fileUrl) throws Exception {
		// 处理结果
		boolean result = false;
		long startTime = System.currentTimeMillis();
		logger.info("同步实时进件-授信申请信息生成额度信息表：[" + DateTool.formatDate(new Date(startTime), DateTool.PATTERN_DATETIME) + "]， 处理开始");
		try {
			TxtFileLoadPluginBatch txtFileLoadPlugin = new TxtFileLoadPluginBatch(fileUrl, "\u0002", "UTF-8", 0, 1000);
			List<TxtFileLoadBean> txtFileLoadList = txtFileLoadPlugin.run(new BdSxapplyBean());
			result = dueData(txtFileLoadList);
			if (txtFileLoadList.size() != 0) {
				while (!txtFileLoadList.get(txtFileLoadList.size() - 1).isReadedComplete) {
					txtFileLoadPlugin.setFirstRead(false);
					txtFileLoadList = txtFileLoadPlugin.run(new BdSxapplyBean());
					if (txtFileLoadList.size() == 0) {
						break;
					}
					result = dueData(txtFileLoadList);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "lmt_prd_cont";
			String errorMsg = "同步实时进件-授信申请信息生成额度信息出错";
			String remark = "同步实时进件-授信申请信息生成额度信息出错，错误信息：" + e.getMessage();
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
			throw new Exception(remark);
		}
		long endTime = System.currentTimeMillis();
		logger.info("同步实时进件-授信申请信息生成额度信息表：[" + DateTool.formatDate(new Date(endTime), DateTool.PATTERN_DATETIME) + "]， 处理结束");
		logger.info("同步实时进件-授信申请信息生成额度信息表，耗时：[" + (endTime - startTime) / 1000.0 + "]秒，处理结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 根据存量的实时进件-授信申请文件数据信息加工初始化授信申请信息 <br>
	 * 0.1:ludayong:2019年5月13日 上午9:08:10:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月13日 上午9:08:10
	 * @date 2019年5月13日 上午9:08:10
	 * @version 0.1
	 */
	public boolean dueData(List<TxtFileLoadBean> txtFileLoadList) {
		logger.info("同步实时进件-授信申请信息生成额度信息表加工处理开始！");
		// 需要新增或者更新的额度信息
		List<LmtPrdContVO> lmtPrdContInfoList = new ArrayList<LmtPrdContVO>();
		// 处理结果
		boolean result = false;
		// 新增或者修改的额度信息数量
		int lmtPrdContInfoNum = 0;
		try {
			for (int i = 0; i < txtFileLoadList.size(); i++) {
				BdSxapplyBean bdSxapplyBean = (BdSxapplyBean) txtFileLoadList.get(i);
				if (BdLoanConstant.NO_0.equals(bdSxapplyBean.getIsblack()) || StringUtil.isNullorBank(bdSxapplyBean.getIsblack())) {
					// 需要新增或者更新的额度信息
					LmtPrdContVO lmtPrdContVO = initLmtPrdContInfo(bdSxapplyBean);
					if (Objects.nonNull(lmtPrdContVO)) {
						lmtPrdContInfoList.add(lmtPrdContVO);
					}
				}
			}
			// 需要新增或者更新的额度信息
			if (Objects.nonNull(lmtPrdContInfoList) && !lmtPrdContInfoList.isEmpty()) {
				// 新增或者更新额度信息
				lmtPrdContInfoNum = lmtPrdContService.insertOrUpdateLmtPrdCont(lmtPrdContInfoList);
			}
			String num_msg = "【额度信息表】插入或更新数据处理结果:" + lmtPrdContInfoNum;
			logger.info(num_msg, "message{}");
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "lmt_prd_cont";
			String errorMsg = "同步实时进件-授信申请信息生成额度信息出错";
			String remark = "同步实时进件-授信申请信息生成额度信息出错，错误信息：" + e.getMessage();
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
		} finally {
			// 清空信息
			lmtPrdContInfoList = null;
			txtFileLoadList = null;
		}
		logger.info("同步实时进件-授信申请信息生成额度信息表加工处理结束！");
		return result;
	}

	/**
	 * 
	 * 初始化授信额度信息 <br>
	 * 0.1:ludayong:2019年5月7日 上午10:52:04:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 上午10:52:04
	 * @date 2019年5月7日 上午10:52:04
	 * @version 0.1
	 */
	public LmtPrdContVO initLmtPrdContInfo(BdSxapplyBean bdSxapplyBean) {
		// 需要新增或者修改的授信额度信息
		LmtPrdContVO lmtPrdContVO = new LmtPrdContVO();
		try {
			// lmt_cont_no 授信协议编号 唯一标志
			lmtPrdContVO.setLmtContNo(generateLmtContNo());
			// lmt_apply_seq 授信申请流水号 关联授信申请信息 SESSIONID 通用字段-会话ID
			lmtPrdContVO.setLmtApplySeq(bdSxapplyBean.getSessionid());
			// cus_id 客户编号 客户建档返回
			// cus_name 客户名称 NAME 通用字段-真实姓名
			lmtPrdContVO.setCusName(bdSxapplyBean.getName());
			// cert_type 证件类型 10100 居民身份证
			lmtPrdContVO.setCertType(SDicCertTypeEnum.IDCARD.getValue());
			// cert_code 证件号码 PRCID 通用字段-身份证号
			lmtPrdContVO.setCertCode(bdSxapplyBean.getPrcid());
			// channel_no 渠道号 05度小满
			lmtPrdContVO.setChannelNo(BdLoanConstant.BD_CHANNEL_NO);
			// prd_id 产品ID ICODE 百度分配的机构码
			lmtPrdContVO.setPrdId(SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.PRD_CODE, bdSxapplyBean.getIcode()));
			// prd_code 产品代码 ICODE 百度分配的机构码
			lmtPrdContVO.setPrdCode(SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.PRD_CODE, bdSxapplyBean.getIcode()));
			// prd_name 产品名称 ICODE 百度分配的机构码
			lmtPrdContVO.setPrdName(SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.PRD_NAME, bdSxapplyBean.getIcode()));
			// prd_type 产品类型
			// case_code 专案编号
			// case_name 专案名称
			// lmt_amt 授信额度 授信申请金额 INITAILAMOUNT 百度授信额度
			if (!StringUtil.isNullorBank(bdSxapplyBean.getInitailamount())) {
				// 单位转换待定
				lmtPrdContVO.setLmtAmt(new BigDecimal(bdSxapplyBean.getInitailamount()));
			}
			// avail_amt 可用额度
			// pre_occ_amt 预占用额度
			// occ_amt 已用额度
			// cyclic_flg 是否循环 "1是 0否"
			lmtPrdContVO.setCyclicFlg(SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.CYCLIC_FLG, bdSxapplyBean.getIcode()));
			// currency_type 币种 CNY人民币
			lmtPrdContVO.setCurrencyType(CurrencyConstant.CNY);
			// term 期限 默认9999
			lmtPrdContVO.setTerm(new BigDecimal(BdLoanConstant.DAY_9999));
			// String term = SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.APPLY_TERM,
			// bdSxapplyTempVO.getIcode());
			// if (!StringUtil.isNullorBank(term)) {
			// lmtPrdContVO.setTerm(new BigDecimal(term));
			// }
			// term_type 期限类型 D日
			lmtPrdContVO.setTermType(BdLoanConstant.TERM_TYPE_D);
			// rate_y 利率(年)
			// assure_means_main 担保方式
			lmtPrdContVO.setAssureMeansMain(BdLoanConstant.ASSURE_MEANS_MAIN_00);
			// assure_means2 担保方式2
			// assure_means3 担保方式3
			// repayment_src_dec 还款来源
			// repayment_mode 还款方式
			// repayment_period 还款周期
			// repayment_period_type 还款周期单位
			// repayment_day_type 还款日类型
			// repayment_day 还款日
			// loan_use 贷款用途 23 消费支出
			lmtPrdContVO.setLoanUse(BdLoanConstant.LOAN_USE_TYPE_23);
			// lmt_status 额度状态 02 有效 03 已失效
			String apprvSts = SDicMappingUtil.getLocalSysDicVal(BdLoanConstant.NLS_APPLY_STATE, bdSxapplyBean.getIsblack());
			lmtPrdContVO.setLmtStatus(apprvSts);
			// start_date 起始日
			String startDate = DueDataUtil.getApplyDateValue(bdSxapplyBean.getTrantime(), BdLoanConstant.NO_0);
			lmtPrdContVO.setStartDate(startDate);
			// expire_date 到期日期
			// if (!StringUtil.isNullorBank(term) && !StringUtil.isNullorBank(startDate)) {
			// lmtPrdContVO.setExpireDate(DateUtility.ADD_DAY(startDate,
			// Integer.parseInt(term)));
			// }
			// 到期日期默认2099-12-31
			lmtPrdContVO.setExpireDate(BdLoanConstant.EXPIRE_DATE);
			// sign_date 签订日期 审批通过的日期
			lmtPrdContVO.setSignDate(startDate);
			// valid_days 授信批复有效期
			// cus_manager 客户经理
			// main_br_id 管理机构
			// chargeoff_br_id 出账机构编号
			// legal_org_code 机构法人代码
			// legal_org_name 机构法人名称
			// frz_serno 冻结流水号
			// loan_account 放款账户 放款账户 BANKCARD 通用字段-银行卡号
			lmtPrdContVO.setLoanAccount(bdSxapplyBean.getBankcard());
			// recv_account 还款账户 还款账户 BANKCARD 通用字段-银行卡号
			lmtPrdContVO.setRecvAccount(bdSxapplyBean.getBankcard());
			// create_time 创建时间 赋值
			// create_user 创建人 赋值
			// last_update_user 最后更新人 赋值
			// last_update_time 最近更新时间 赋值
			final String createUser = "admin";
			// create_user 创建人
			lmtPrdContVO.setCreateUser(createUser);
			// create_time 创建时间
			lmtPrdContVO.setCreateTime(DueDataUtil.getApplyDateValue(bdSxapplyBean.getTrantime(), BdLoanConstant.YES_1));
			// last_update_user 最后修改人
			lmtPrdContVO.setLastUpdateUser(createUser);
			// last_update_time 最后修改时间
			lmtPrdContVO.setLastUpdateTime(DateTool.getCurrentDateTime());
			// approve_status 审批状态
			return lmtPrdContVO;
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "lmt_prd_cont";
			String remark = "初始化额度信息出错，授信申请流水号：" + bdSxapplyBean.getSessionid();
			String errorMsg = "初始化额度信息出错，异常信息：" + e.getMessage();
			logger.error(errorMsg);
			// 记录异常信息
			this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			return null;
		}
	}

	/**
	 * 
	 * 生成LMT系统的交易流水号(LmtContNo) <br>
	 * 0.1:ludayong:2019年5月7日 下午4:00:13:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 下午4:00:13
	 * @date 2019年5月7日 下午4:00:13
	 * @version 0.1
	 */
	public String generateLmtContNo() {
		PatternedLimitableSeqService sequenceService = SpringContextUtils.getBean(PatternedLimitableSeqService.class);
		String lmtContNo = sequenceService.getPatternedSequence("LMT", pattern);
		return lmtContNo;
	}

	/**
	 * 
	 * 记录异常信息 <br>
	 * 0.1:ludayong:2019年5月7日 上午11:31:23:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 上午11:31:23
	 * @date 2019年5月7日 上午11:31:23
	 * @version 0.1
	 */
	private void addErrorInfo(String tableName, String errorType, String errorMsg, String remark) {
		AccoutErroTempVO accoutErroTempVO = new AccoutErroTempVO();
		// 表名
		accoutErroTempVO.setTableName(tableName);
		// 错误级别
		accoutErroTempVO.setErroType(errorType);
		// 错误信息
		accoutErroTempVO.setErroMsg(errorMsg);
		// 备注
		accoutErroTempVO.setRemark(remark);
		// 创建时间
		accoutErroTempVO.setCreateData(DateTool.getCurrentDateTime());
		// 修改时间
		accoutErroTempVO.setLastModifyTime(DateTool.getCurrentDateTime());
		// 记录异常信息
		accoutErroTempService.insert(accoutErroTempVO);
	}
}
